package parsexml;

import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import parsexml.constant.XmlNodeConstant;
import parsexml.enity.XmlClass;
import parsexml.enity.XmlStudent;
import parsexml.enity.XmlSubject;

import java.io.*;
import java.util.Iterator;
import java.util.List;

/**
 * @author 李栋
 * @version 1.0.0
 * @className ParseXmlTest.java
 * @createTime 2021年07月14日 20:22:00
 */
public class ParseXmlByDom4jHandlerTest {

    private static final Logger logger = LoggerFactory.getLogger(ParseXmlByDom4jHandlerTest.class);


    public InputStream getInputStream() throws FileNotFoundException {
        File file = new File("K:\\JavaTest\\src\\main\\java\\parsexml\\ClassDemo.xml");
        return new FileInputStream(file);
    }

    /**
     * Dom 4j 方式解析
     * 这种方式还是会全部加载到内存中，还是很肯爹的
     */
    @Test
    public void parseXmlByDom4jHandler() {
        //1.创建Reader对象
        SAXReader reader = new SAXReader();
        XmlClass xmlClass = new XmlClass();
        reader.addHandler("/DOCUMNET/CLASS", new XmlClassHandler(xmlClass));
        reader.addHandler("/DOCUMNET/CLASS/STUDENT", new XmlStudentHandler(xmlClass));
        InputStream inputStream = null;
        try {
            inputStream = getInputStream();
            reader.read(inputStream);
        } catch (DocumentException | FileNotFoundException e) {
            logger.error("Error Occur:{}", e.getMessage(), e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                logger.error("Error Occur:{}", e.getMessage());
            }
        }
        logger.info("test");
    }

    /**
     * 监听器
     */
    private class XmlClassHandler implements ElementHandler {
        private final XmlClass xmlClass;

        public XmlClassHandler(XmlClass xmlClass) {
            this.xmlClass = xmlClass;
        }

        @Override
        public void onStart(ElementPath elementPath) {
            // 释放节点
            elementPath.getCurrent().detach();
        }

        @Override
        public void onEnd(ElementPath elementPath) {
            Element element = elementPath.getCurrent();
            Iterator<Element> childElementIterator = element.elementIterator();
            while (childElementIterator.hasNext()) {
                Element childElement = childElementIterator.next();
                String name = childElement.getName();
                String stringValue = childElement.getStringValue();
                if (XmlNodeConstant.CLASS_NAME.equalsIgnoreCase(name)) {
                    xmlClass.setClassName(stringValue);
                }
                if (XmlNodeConstant.CLASS_CNO.equalsIgnoreCase(name)) {
                    xmlClass.setClassCno(stringValue);
                }
            }
            element.detach();
        }
    }

    /**
     * 监听器
     */
    private class XmlStudentHandler implements ElementHandler {

        private final XmlClass xmlClass;

        public XmlStudentHandler(XmlClass xmlClass) {
            this.xmlClass = xmlClass;
        }

        @Override
        public void onStart(ElementPath elementPath) {
            elementPath.getCurrent().detach();
        }

        @Override
        public void onEnd(ElementPath elementPath) {
            Element element = elementPath.getCurrent();
            XmlStudent xmlStudent = new XmlStudent();
            packageXmlStudent(element.content(), xmlStudent);
            xmlClass.getXmlStudents().add(xmlStudent);
            element.detach();
        }
    }


    /**
     * 组装学生信息
     *
     * @param content
     * @param xmlStudent
     */
    private void packageXmlStudent(List<Node> content, XmlStudent xmlStudent) {
        for (Node studentNode : content) {
            String tableNodeName = studentNode.getName();
            String tableNodeStringValue = studentNode.getStringValue();
            if (XmlNodeConstant.STUDENT_SNO.equalsIgnoreCase(tableNodeName)) {
                xmlStudent.setSno(tableNodeStringValue);
            }
            if (XmlNodeConstant.NAME.equalsIgnoreCase(tableNodeName)) {
                xmlStudent.setName(tableNodeStringValue);
            }
            if (XmlNodeConstant.GENDER.equalsIgnoreCase(tableNodeName)) {
                xmlStudent.setGender(tableNodeStringValue);
            }
            if (XmlNodeConstant.SUBJECT.equalsIgnoreCase(tableNodeName)) {
                XmlSubject xmlSubject = new XmlSubject();
                packageXmlSubject(studentNode, xmlSubject);
                xmlStudent.getXmlSubjects().add(xmlSubject);
            }

        }
    }

    /**
     * 组装科目信息
     *
     * @param studentNode
     * @param xmlSubject
     */
    private void packageXmlSubject(Node studentNode, XmlSubject xmlSubject) {
        List<Node> subjectNodes = ((Branch) studentNode).content();
        for (Node subjectNode : subjectNodes) {
            String columnNodeName = subjectNode.getName();
            String columnNodeString = subjectNode.getStringValue();
            if (XmlNodeConstant.NAME.equalsIgnoreCase(columnNodeName)) {
                xmlSubject.setSubjectName(columnNodeString);
            }
            if (XmlNodeConstant.SUBJECT_NO.equalsIgnoreCase(columnNodeName)) {
                xmlSubject.setSubjectNo(columnNodeString);
            }
            if (XmlNodeConstant.SCORE.equalsIgnoreCase(columnNodeName)) {
                xmlSubject.setScore(Float.parseFloat(columnNodeString));
            }
        }
    }


}
